/* #include <iostream> */
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "libvid.h"
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
/* #include <ffmpeg/avformat.h> */
/* avcodec_decode_audio3*/



/* void packet_queue_init(PacketQueue *q) */
/*  { */
/*   memset(q, 0, sizeof(PacketQueue)); */
/*   q->mutex = SDL_CreateMutex(); */
/*   q->cond = SDL_CreateCond(); */
/* } */
/* int packet_queue_put(PacketQueue *q, AVPacket *pkt) { */

/*   AVPacketList *pkt1; */
/*   if(av_dup_packet(pkt) < 0) { */
/*     return -1; */
/*   } */
/*   pkt1 = av_malloc(sizeof(AVPacketList)); */
/*   if (!pkt1) */
/*     return -1; */
/*   pkt1->pkt = *pkt; */
/*   pkt1->next = NULL; */

/*   SDL_LockMutex(q->mutex); */

/*   if (!q->last_pkt) */
/*     q->first_pkt = pkt1; */
/*   else */
/*     q->last_pkt->next = pkt1; */
/*   q->last_pkt = pkt1; */
/*   q->nb_packets++; */
/*   q->size += pkt1->pkt.size; */
/*   SDL_CondSignal(q->cond); */

/*   SDL_UnlockMutex(q->mutex); */
/*   return 0; */
/* } */
/* static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) */
/* { */
/*   AVPacketList *pkt1; */
/*   int ret; */
/*   int quit; */


/*   SDL_LockMutex(q->mutex); */

/*   for(;;) { */

/*     if(quit) */
/*  { */
/*       ret = -1; */
/*       break; */
/*     } */

/*     pkt1 = q->first_pkt; */
/*     if (pkt1) { */
/*       q->first_pkt = pkt1->next; */
/*       if (!q->first_pkt) */
/* 	q->last_pkt = NULL; */
/*       q->nb_packets--; */
/*       q->size -= pkt1->pkt.size; */
/*       *pkt = pkt1->pkt; */
/*       av_free(pkt1); */
/*       ret = 1; */
/*       break; */
/*     } else if (!block) { */
/*       ret = 0; */
/*       break; */
/*     } else { */
/*       SDL_CondWait(q->cond, q->mutex); */
/*     } */
/*   } */
/*   SDL_UnlockMutex(q->mutex); */
/*   return ret; */
/* } */


/* //video::video(char* pFichierVideo) */
/* //value veo (char* pFichierVideo) */
/* //{ */
/* //av_register_all(); //Enregistre les codecs de la librairie */
/* //} */
/*   //Teste si on peut ouvrir ou non la vidéo */
/*   // if (av_open_input_file(&pVideoFormat, pFichierVideo, NULL, 0, NULL) != 0) */
/*   // { */
/*   //  cout << "Impossible d'ouvrir la vidéo " << pFichierVideo << endl; */
/*   //  exit(EXIT_FAILURE); */
/*   //} */

/*   //Recherche les informations sur la vidéo */
/*   /\* if (av_find_stream_info(pVideoFormat) < 0) */
/*     { */
/*       cout << "Impossible de trouver les informations de la vidéo " << pFichierVideo << endl; */
/*       exit(EXIT_FAILURE); */
/*     } */
/*   dump_format(pVideoFormat, 0, pFichierVideo, 0); */
/*   } */





void			audio_codec(void)
{
  unsigned int		i;
  AVCodec		*pCodec;
  AVCodec		*pAudio;
  video			s;
  audio			a;

  /* Regarde le type de codec à utiliser */

  s.videoStream = -1;
  a.fluxAudio = -1;

  for(i=0; i< s.pFormatCtx->nb_streams; i++)
  {
    if (s.pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
    {
      s.videoStream = i;
      break;
    }

    if (s.pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
    {
      a.fluxAudio = i;
      break;
    }
  }

  /* Flux vidéo non trouvé */
  if (s.videoStream == -1 || a.fluxAudio == -1)
    exit(EXIT_FAILURE);

  //Spécification du son
 a.pAudioCodec = s.pFormatCtx->streams[a.fluxAudio]->codec;
 // a.specRecherche.freq = a.pAudioCodec->sample_rate; //La fréquence du son

 // a.specRecherche.format = AUDIO_S16SYS; //Format du son(codec à utiliser)
 // a.specRecherche.channels = a.pAudioCodec->channels; //Les canneaux(mono, stéréo etc.)

 // a.specRecherche.silence = 0;
 //  a.specRecherche.samples = 1024;

  //a.specRecherche.callback = audio_callback;
  //a.specRecherche.userdata = a.pAudioCodec;

  // if (SDL_OpenAudio(&a.specRecherche, &a.spec) <0)
  // {
      // cout << "SDL_OpenAudio: " << SDL_GetError() << endl;
  //  exit(EXIT_FAILURE);
  // }

  pAudio = avcodec_find_decoder(a.pAudioCodec->codec_id);
  if (!pAudio)
    {
      //cout << "Codec non supporté" << endl;
      exit(EXIT_FAILURE);
    }

  if (avcodec_open(a.pAudioCodec, pAudio) < 0)
    {
      //cout << "Impossible d'ouvrir le codec audio" << endl;
      exit(EXIT_FAILURE);
    }
  // packet_queue_init(&a.queuePaquet);
  //SDL_PauseAudio(0);

  /* Récupère un pointeur du codec pour le flux vidéo */
  pCodec = s.pFormatCtx->streams[s.videoStream]->codec;

  /* Recherche le décodeur suivant l'ID du codec. */
  s.pCodec = avcodec_find_decoder(s.pCodec->id);
  if (s.pCodec == NULL)
  {
    //      cout << "Le codec de la vidéo n'est pas supporté par FFMPEG" << endl;
    exit(EXIT_FAILURE);
  }

  //Ouvre le codec
  if (avcodec_open(s.pCodec, pCodec) < 0)
    {
      //  cout << "Impossible d'ouvrir le codec" << endl;
      exit(EXIT_FAILURE);
    }
}

/*
void audio_callback(void *donnee, Uint8 *flux, int longeur)
{
  audio a;
  a.pAudioCodec = (AVCodecContext *)donnee;
  int longeur1, tailleAudio;

  static uint8_t bufferAudio[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
  static unsigned int tailleBufferAudio = 0;
  static unsigned int bufferAudioIndex = 0;

  while(longeur > 0)
    {
      if(bufferAudioIndex >= tailleBufferAudio)
	{
	  bufferAudioIndex = audio_decode_frame(a.pAudioCodec, bufferAudio, sizeof(bufferAudio));
	  if(tailleAudio < 0)
	    {
	      tailleBufferAudio = 1024;
	      memset(bufferAudio, 0, tailleBufferAudio);
	    }
	  else
	    {
	      tailleBufferAudio = (unsigned int)bufferAudio;
	    }

	  bufferAudioIndex = 0;
	}
      longeur1 = tailleBufferAudio - bufferAudioIndex;
      if(longeur > longeur1)

	longeur = longeur;
      memcpy(flux, (uint8_t *)bufferAudio + bufferAudioIndex, longeur);

      longeur -= longeur;
      flux += longeur1;

      bufferAudioIndex += longeur1;
    }
}
*/
/* traitement packet: initialisation*/
/*
void audio_packet_queue_init(PacketQueue *q)
{
  memset(q, 0, sizeof(PacketQueue));
  q->mutex = SDL_CreateMutex();
  q->cond = SDL_CreateCond();
}

int audio_packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
  AVPacketList *pkt1;
  if(av_dup_packet(pkt) < 0)
    {
      return -1;
    }

  pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList));
  if (!pkt1)
    {
      return -1;
    }
  pkt1->pkt = *pkt;
  pkt1->next = NULL;

  SDL_LockMutex(q->mutex);

  if (!q->last_pkt)
    {
      q->first_pkt = pkt1;
    }
  else
    q->last_pkt->next = pkt1;
  q->last_pkt = pkt1;
  q->nb_packets++;
  q->size += pkt1->pkt.size;
  SDL_CondSignal(q->cond);
  SDL_UnlockMutex(q->mutex);
  return 0;
}
*/
//Fonction de decodage

int		audio_audio_decode_frame(AVCodecContext		*aCodecCtx,
					 uint8_t		*audio_buf,
					 int			buf_size)
{
  //  video s;
   audio a;
  static AVPacket pkt;
  static uint8_t *audio_pkt_data = NULL;
  static int audio_pkt_size = 0;
 int quit = 0;

  int len1, data_size;

  for(;;)
   {
      while(audio_pkt_size > 0)
	{
	  data_size = buf_size;
	  len1 = avcodec_decode_audio3(aCodecCtx, (int16_t *)audio_buf, /*&data_size,*/ audio_pkt_size, audio_pkt_data);
	  if(len1 < 0)
	    {
	      audio_pkt_size = 0;
	      break;
	    }

	  audio_pkt_data += len1;
	  audio_pkt_size -= len1;
	  if(data_size <= 0)
	    {
	      continue;
	    }
	  return data_size;
	}
      if(pkt.data)
	av_free_packet(&pkt);
      if(quit)
	{
	  return -1;
	}
      // if(packet_queue_get(&a.queuePaquet, &pkt, 1) < 0)
      //	{
      //return -1;
	  //	}

      audio_pkt_data = pkt.data;
      audio_pkt_size = pkt.size;
       }
}


/*
int audio_packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
{
  //audio a;
  //video s;
  AVPacketList *pkt1;
  int ret;
  int quit;
  SDL_LockMutex(q->mutex);

  for(;;)
    {
      if(quit)
	{
	  ret = -1;
	  break;
	}
      pkt1 = q->first_pkt;
      if (pkt1)
	{
	  q->first_pkt = pkt1->next;
	  if (!q->first_pkt)
	    q->last_pkt = NULL;
	  q->nb_packets--;
	  q->size -= pkt1->pkt.size;
	  *pkt = pkt1->pkt;
	  av_free(pkt1);
	  ret = 1;
	  break;
	}
      else if (!block)
	{
	  ret = 0;
	  break;
	}
      else
	{
	  SDL_CondWait(q->cond, q->mutex);
	}
    }
  SDL_UnlockMutex(q->mutex);
  return ret;
}
*/
